package jmine.tec.json;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * JSONArray que eh uma lista
 * 
 * @author takeshi
 */
public class JSONArray extends AbstractJSONObject {

    private final List<JSON> elements;

    /**
     * 
     */
    public JSONArray() {
        this.elements = new ArrayList<JSON>();
    }

    /**
     * @param elements {@link Collection}
     */
    public JSONArray(Collection<? extends JSON> elements) {
        super();
        this.elements = new ArrayList<JSON>(elements);
    }

    /**
     * Adiciona um elemento
     * 
     * @param element JSON
     */
    public void add(JSON element) {
        this.elements.add(element);
    }

    /**
     * {@inheritDoc}
     */
    public JSON getProperty(String propertyName) {
        return this.getProperty(Integer.parseInt(propertyName));
    }

    /**
     * {@inheritDoc}
     */
    public JSON getProperty(int index) {
        return this.elements.get(index);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<JSON> getPropertyValues() {
        return new ArrayList<JSON>(this.elements);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getSize() {
        return this.elements.size();
    }

    /**
     * {@inheritDoc}
     */
    public Collection<String> getPropertyNames() {
        final int n = this.elements.size();
        List<String> list = new ArrayList<String>(n);
        for (int i = 0; i < n; i++) {
            list.add(String.valueOf(i));
        }
        return list;
    }

    /**
     * {@inheritDoc}
     */
    public void setProperty(String propertyName, JSON value) {
        int index = Integer.parseInt(propertyName);
        this.elements.set(index, value);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return this.elements.toString();
    }

    /**
     * {@inheritDoc}
     * 
     * @see java.lang.Object#hashCode()
     */

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((this.elements == null) ? 0 : this.elements.hashCode());
        return result;
    }

    /**
     * {@inheritDoc}
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (this.getClass() != obj.getClass()) {
            return false;
        }
        JSONArray other = (JSONArray) obj;
        if (this.elements == null) {
            if (other.elements != null) {
                return false;
            }
        } else if (!this.elements.equals(other.elements)) {
            return false;
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public Writer write(Writer writer) throws IOException {
        writer.append("[");
        Iterator<JSON> it = this.elements.iterator();
        if (it.hasNext()) {
            it.next().write(writer);
        }
        while (it.hasNext()) {
            writer.append(',');
            it.next().write(writer);
        }
        writer.append("]");
        return writer;
    }
}
